package com.itlong.cloud.controller.property;

import com.itlong.cloud.POJO.DTO.property.PropertyAdminInfoDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyOperateConditionDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyProjectGetCommunityInfoDTO;
import com.itlong.cloud.POJO.PO.PropertyUserInfoPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.property.PropertyOperateConditionVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectCommunityInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.annotation.UnParamEncrypt;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.iottp.IIotTpSmsServiceClient;
import com.itlong.cloud.project.property.IPropertyCommunityInfoServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.property.IPropertyHouseHoldInfoServiceClient;
import com.itlong.cloud.user.propertyapp.IPropertyAppUserInfoServiceClient;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *    小区信息管理控制器
 * </desc>
 *
 * @createDate 2017-10-10
 */
@RestController
@RequestMapping("project/communityInfo")
@RefreshScope
public class PropertyCommunityInfoController extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(PropertyCommunityInfoController.class);

    @Autowired
    IPropertyCommunityInfoServiceClient iPropertyCommunityInfoServiceClient; //小区信息服务接口协议提供对象


    @Autowired
    IPropertyHouseHoldInfoServiceClient iPropertyHouseHoldInfoServiceClient; //小区住户信息

    @Autowired
    IPropertyAppUserInfoServiceClient iPropertyAppUserInfoServiceClient;

    @Autowired
    RedisService redisService;

    @Autowired
    IIotTpSmsServiceClient iIotTpSmsServiceClient;

    @Value("${" + PlatformConstants.PROPERTY_USER_TOKEN_KEY + "}")
    String userTokenKey;

    /**
     * <desc>
     *      查询小区信息及相关统计信息
     * <desc/>
     * @param  propertyProjectGetCommunityInfoDTO 查询小区信息数据传输对象
     * @return 小区相关信息返回对象
     * @author ZiXuan
     * @createDate 2017-10-11
     */
    @RequestMapping(path = "/getCommunityInfo",method = RequestMethod.POST)
    @ResponseBody
    public Object getCommunityInfo(PropertyProjectGetCommunityInfoDTO propertyProjectGetCommunityInfoDTO){

        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyProjectGetCommunityInfoDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyProjectGetCommunityInfoDTO.class, request);
            if (null == propertyProjectGetCommunityInfoDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            //项目编号为主键
            if ((StringUtils.isBlank(propertyProjectGetCommunityInfoDTO.getProjectId()))) {
                //项目编号不能为空
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            PropertyProjectCommunityInfoVO propertyProjectCommunityInfoVO = iPropertyCommunityInfoServiceClient.
                    getCommunityInfo(propertyProjectGetCommunityInfoDTO);
            if (StringUtils.isNotBlank(propertyProjectCommunityInfoVO.getEngineerCode())) {
                String encode = Base64.encode(DesEncryptUtil.Encrypt(URLEncoder.encode(
                        new String(propertyProjectCommunityInfoVO.getEngineerCode().getBytes()), "utf-8").getBytes(), userTokenKey));
                propertyProjectCommunityInfoVO.setEngineerCode(encode);
            }
            Integer userCount = iPropertyHouseHoldInfoServiceClient.getAllHouseProjectInfo(propertyProjectGetCommunityInfoDTO.getProjectId());
            propertyProjectCommunityInfoVO.setUserCount(userCount);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), propertyProjectCommunityInfoVO);
        } catch (Exception e) {
            throw new DataAccessException("【物业_项目_小区信息】查询小区信息失败", e);
        }
    }

    /**
     * <desc>
     *      查询物业运营情况
     * </desc>
     *
     * @param propertyOperateConditionDTO 物业运营情况DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/05/24
     */
    @ResponseBody
    @PostMapping("getOperateCondition")
    public Object getOperateCondition(PropertyOperateConditionDTO propertyOperateConditionDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyOperateConditionDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyOperateConditionDTO.class, request);
            if (propertyOperateConditionDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(propertyOperateConditionDTO.getProjectId())) {
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            PropertyOperateConditionVO propertyOperateConditionVO = iPropertyCommunityInfoServiceClient.getOperateCondition(propertyOperateConditionDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), propertyOperateConditionVO);
        } catch (Exception e) {
            throw new DataAccessException("【物业_项目_小区信息】查询物业运营情况失败", e);
        }
    }

    /**
     * <desc>
     *      获取通行占比数据
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/10/16
     */
    @ResponseBody
    @PostMapping("getPassPercent")
    public Object getPassPercent(){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            PropertyProjectGetCommunityInfoDTO propertyProjectGetCommunityInfoDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyProjectGetCommunityInfoDTO.class, request);
            if (propertyProjectGetCommunityInfoDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(propertyProjectGetCommunityInfoDTO.getProjectId())) {
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            List<Map<String, Object>> data = iPropertyCommunityInfoServiceClient.getPassPercent(propertyProjectGetCommunityInfoDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【物业_项目_小区信息】获取通行占比数据失败", e);
        }
    }

    /**
     * <desc>
     *      修改小区信息
     * <desc/>
     * @param  paramDTO 修改小区信息数据传输对象
     * @return MessageVO 标准格式化响应结果
     * @author ZiXuan
     * @createDate 2017-10-23
     */
    @LoggerInfo(operateDesc = LogDescConstant.UPDATE_COMMUNITYINFO_LOG_DESC)
    @RequestMapping(path = "/updateCommunityInfo",method = RequestMethod.POST)
    @ResponseBody
    public Object updateCommunityInfo(PropertyProjectGetCommunityInfoDTO paramDTO){

        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            paramDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyProjectGetCommunityInfoDTO.class, request);
            if (null == paramDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 解密工程密码
            if (StringUtils.isNotBlank(paramDTO.getEngineerCode())) {
                String engineerCode = UserTokenUtil.getPassword(paramDTO.getEngineerCode(), userTokenKey);
                paramDTO.setEngineerCode(engineerCode);
            }
            if ((StringUtils.isEmpty(paramDTO.getProjectId()))) {
                //项目编号不能为空
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }

            if (!StringUtils.isBlank(paramDTO.getEngineerCode()) && (!paramDTO.getEngineerCode().matches("[0-9]{0,6}"))){
                return new MessageVO(PropertyErrorCodeEnum.PROJECT_ENGINEER_CODE_FORMAT_INVALID_ERR.getErrorCode());
            }

            iPropertyCommunityInfoServiceClient.updateCommunityInfo(paramDTO);
            return new MessageVO(paramDTO.getProjectId(),BaseErrorCodeEnum.SUCCESS.getErrorCode());

        } catch (Exception e) {
            throw new DataAccessException("【物业_项目_小区信息】修改小区信息失败", e);
        }
    }

    /**
     * <desc>
     *      物业管理员手机号获取验证码(物业app版本之后取消管理员限制)
     * </desc>
     *
     * @param propertyAdminInfoDTO 物业管理员信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/08
     */
    @UnAuthAccessRequired
    @ResponseBody
    @PostMapping("getVerificationCode")
    public Object getVerificationCode(PropertyAdminInfoDTO propertyAdminInfoDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyAdminInfoDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAdminInfoDTO.class, request);
            if (propertyAdminInfoDTO == null/* || StringUtils.isBlank(propertyAdminInfoDTO.getLoginUserId())*/) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(propertyAdminInfoDTO.getAdministratorPhone())) {
                return new MessageVO(PropertyErrorCodeEnum.PHONE_NUM_EMPTY_ERR.getErrorCode());
            }
            // 校验管理员身份
//            PropertyUserInfoPO propertyUserInfoPO = iPropertyCommunityInfoServiceClient.getPropertyUserInfoByUserId(propertyAdminInfoDTO.getLoginUserId());
//            if (!("3".equals(propertyUserInfoPO.getRoleId()) || "4".equals(propertyUserInfoPO.getRoleId()) || "5".equals(propertyUserInfoPO.getRoleId()))) {
//                return new MessageVO(PropertyErrorCodeEnum.PROPERTY_USER_ADMIN_ERR.getErrorCode());
//            }

            String smsCode = NumberHandlerUtil.randomNum(6);
            while (smsCode.substring(0, 1).equals("0")) {
                smsCode = NumberHandlerUtil.randomNum(6);
            }
            String content = "验证码：" + smsCode + "，该验证码将在30分钟后失效";
            Map<String, Object> messageCountMap = (HashMap) redisService.getObject(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_COUNT + propertyAdminInfoDTO.getAdministratorPhone(), HashMap.class);
            if (messageCountMap == null) {
                messageCountMap = new HashMap<>();
            }
            Integer count = (Integer) messageCountMap.get("count");
            if (count == null) {
                count = 1;
            } else {
                count++;
            }
            if (count > 3) {
                return new MessageVO(PropertyErrorCodeEnum.BANK_CARD_SEND_MESSAGE_COUNT_SURPASS.getErrorCode());
            } else {
                messageCountMap.put("count", count);
                messageCountMap.put("smsCode", smsCode);
                iIotTpSmsServiceClient.sendSmsCodeByPhone(propertyAdminInfoDTO.getAdministratorPhone(), content);
                redisService.set(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_COUNT + propertyAdminInfoDTO.getAdministratorPhone(), RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_COUNT_TIME, messageCountMap);
                //保存验证码
                redisService.set(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_KEY + propertyAdminInfoDTO.getAdministratorPhone(), RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_CACHE_TIME, smsCode);
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }
        } catch (Exception e) {
            throw new DataAccessException("【物业_项目_小区信息】物业管理员手机号获取验证码失败", e);
        }
    }

    /**
     * <desc>
     *      物业管理员修改信息(物业app版本之后取消管理员限制)
     * </desc>
     *
     * @param propertyAdminInfoDTO 物业管理员信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/08
     */
    @UnAuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.UPDATE_PROPERTY_ADMIN_INFO_LOG_DESC)
    @ResponseBody
    @PostMapping("update")
    public Object update(PropertyAdminInfoDTO propertyAdminInfoDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyAdminInfoDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAdminInfoDTO.class, request);
            if (propertyAdminInfoDTO == null ||
                    (StringUtils.isBlank(propertyAdminInfoDTO.getLoginUserId()) && StringUtils.isBlank(propertyAdminInfoDTO.getUserName()))) { // 找回密码时没有登录，检验userName
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 校验管理员身份
//            PropertyUserInfoPO propertyUserInfoPO = iPropertyCommunityInfoServiceClient.getPropertyUserInfoByUserId(propertyAdminInfoDTO.getLoginUserId());
//            if (!("3".equals(propertyUserInfoPO.getRoleId()) || "4".equals(propertyUserInfoPO.getRoleId()) || "5".equals(propertyUserInfoPO.getRoleId()))) {
//                return new MessageVO(PropertyErrorCodeEnum.PROPERTY_USER_ADMIN_ERR.getErrorCode());
//            }
            if (propertyAdminInfoDTO.getStep() == 3 && propertyAdminInfoDTO.getDistrictId() == null) {
                propertyAdminInfoDTO.setDistrictId("");
            }
            if (!NumberHandlerUtil.isInRange(propertyAdminInfoDTO.getStep(), 1, 4)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            if (propertyAdminInfoDTO.getStep() == 4) {
                if (StringUtils.isBlank(propertyAdminInfoDTO.getAdministratorPhone())) {
                    return new MessageVO(PropertyErrorCodeEnum.PHONE_NUM_EMPTY_ERR.getErrorCode());
                }
                if (StringUtils.isBlank(propertyAdminInfoDTO.getCode())) {
                    return new MessageVO(PropertyErrorCodeEnum.MESSAGE_CODE_EMPTY_ERR.getErrorCode());
                }
                // 校验验证码
                String smsCode = (String) redisService.getObject(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_KEY + propertyAdminInfoDTO.getAdministratorPhone(), String.class);
                if (!propertyAdminInfoDTO.getCode().equals(smsCode)) {
                    return new MessageVO(PropertyErrorCodeEnum.BANK_CARD_SEND_MESSAGE_ERROR.getErrorCode());
                } else {
                    // 校验通过之后，更新最后一次安全验证时间
                    iPropertyCommunityInfoServiceClient.update(propertyAdminInfoDTO);
                    redisService.del(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_KEY + propertyAdminInfoDTO.getAdministratorPhone());
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
                }
            }
            if (propertyAdminInfoDTO.getStep() == 1 && StringUtils.isBlank(propertyAdminInfoDTO.getAdministratorPhone())) {
                return new MessageVO(PropertyErrorCodeEnum.PHONE_NUM_EMPTY_ERR.getErrorCode());
            }
            if (propertyAdminInfoDTO.getStep() == 1 && StringUtils.isBlank(propertyAdminInfoDTO.getCode())) {
                return new MessageVO(PropertyErrorCodeEnum.MESSAGE_CODE_EMPTY_ERR.getErrorCode());
            }
            if ((propertyAdminInfoDTO.getStep() == 2 && StringUtils.isBlank(propertyAdminInfoDTO.getPassword()))
                    || (propertyAdminInfoDTO.getStep() == 3 && (StringUtils.isBlank(propertyAdminInfoDTO.getPropertyName()) || StringUtils.isBlank(propertyAdminInfoDTO.getPropertyPhone())
                    || StringUtils.isBlank(propertyAdminInfoDTO.getCountryId()) || StringUtils.isBlank(propertyAdminInfoDTO.getProvinceId())
                    || StringUtils.isBlank(propertyAdminInfoDTO.getCityId()) || propertyAdminInfoDTO.getDistrictId() == null // 直辖市时没有区id，与前端沟通过，方便判断是否完善信息，直辖市时传空字符串
                    || StringUtils.isBlank(propertyAdminInfoDTO.getAddress()) || StringUtils.isBlank(propertyAdminInfoDTO.getPosition())))) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (propertyAdminInfoDTO.getStep() == 3 && StringUtils.isBlank(propertyAdminInfoDTO.getProjectId())) {
                return new MessageVO(PropertyErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            if (propertyAdminInfoDTO.getStep() == 1) {
                // 校验验证码
                String smsCode = (String) redisService.getObject(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_KEY + propertyAdminInfoDTO.getAdministratorPhone(), String.class);
                if (!propertyAdminInfoDTO.getCode().equals(smsCode)) {
                    return new MessageVO(PropertyErrorCodeEnum.BANK_CARD_SEND_MESSAGE_ERROR.getErrorCode());
                } else {
                    redisService.del(RedisConstant.PROPERTY_UPDATE_PHONE_SEND_MESSAGE_KEY + propertyAdminInfoDTO.getAdministratorPhone());
                }
            }
            if (propertyAdminInfoDTO.getStep() == 2) {
                //解密密码
                String passwordStr = UserTokenUtil.getPassword(propertyAdminInfoDTO.getPassword(), userTokenKey);
                if (StringUtils.isBlank(passwordStr)) {
                    return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
                }
                if (passwordStr.equals("itlong@111")) {
                    return new MessageVO(PropertyErrorCodeEnum.USER_PASSWORD_DEFAULT_ERR.getErrorCode());
                }
                propertyAdminInfoDTO.setPassword(passwordStr);
            }
            iPropertyCommunityInfoServiceClient.update(propertyAdminInfoDTO);
            if(propertyAdminInfoDTO.getStep() == 1){
                PropertyUserInfoPO infoPO = new PropertyUserInfoPO();
                infoPO.setUserId(propertyAdminInfoDTO.getLoginUserId());
                infoPO.setAdministratorPhone(propertyAdminInfoDTO.getAdministratorPhone());
                iPropertyAppUserInfoServiceClient.savePropertyUserSipInfo(infoPO,propertyAdminInfoDTO.getProjectId(),2);
            }
            return new MessageVO(StringUtils.isBlank(propertyAdminInfoDTO.getLoginUserId()) ? propertyAdminInfoDTO.getUserName() : propertyAdminInfoDTO.getLoginUserId(),
                    BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_项目_小区信息】物业管理员修改信息失败", e);
        }
    }

    /**
     * <desc>
     *      初始化 物业项目人员类型表中的基础数据 只调取一次
     * </desc>
     *
     * @author Jugaung.S
     * @createDate 2021/04/12
     */
    @UnAuthAccessRequired
    @UnParamEncrypt
    @ResponseBody
    @PostMapping("modifyPropertyUserTypeData")
    public Object modifyPropertyUserTypeData(PropertyAdminInfoDTO propertyAdminInfoDTO){
        try {
                iPropertyAppUserInfoServiceClient.modifyPropertyUserTypeData();
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【初始化】物业项目人员类型表中的基础数据失败", e);
        }
    }
}
